package com.zhan.drugStore.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Field;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Bean转换工具类 使用此工具要注意，必须是public修饰的class才能转换，否则不能使用，本类中不支持属性为集合的复制，会将target中的集合变量设置为空
 */
public class BeanUtils extends org.springframework.beans.BeanUtils
{
	private static final Logger logger = LoggerFactory.getLogger(BeanUtils.class);
	
	/**
	 * 忽略字段
	 */
	public static final String[] IGNORE = {
		"maker", "makeTime", "revoker", "revokeTime", "status", "lastAccess"
	};
	
	public static String[] copyProperties(String[] source, String... ignoreProperties)
	{
		if (ignoreProperties == null || ignoreProperties.length == 0)
		{
			return source;
		}
		else if (source == null || source.length == 0)
		{
			return ignoreProperties;
		}
		else
		{
			System.arraycopy(ignoreProperties, 0, source, source.length, ignoreProperties.length);
		}
		
		return source;
	}
	
	/**
	 * 将给定的对象转换为指定的对象
	 * 
	 * @author QZF
	 * @param source
	 * @param target
	 * @param ignoreProperties
	 * @return
	 */
	public static <S, T> T objToObj(S source, T target, String... ignoreProperties)
	{
		copyProperties(source, target, ignoreProperties);
		SetListToNone(target);
		return target;
	}

	/**
	 * 将给定的对象转换为指定的对象
	 * 
	 * @param source
	 * @param targetClazz
	 * @param ignoreProperties
	 * @return
	 */
	public static <S, T> T objToObj(S source, Class<T> targetClazz, String... ignoreProperties)
	{
		if (source == null)
		{
			return null;
		}

		if (targetClazz == null)
		{
			throw new RuntimeException("Target must not be null");
		}

		T target = null;

		try
		{
			target = targetClazz.newInstance();
		}
		catch (Throwable e)
		{
			throw new RuntimeException("Could not newInstance target '" + targetClazz.getName() + "'", e);
		}

		objToObj(source, target);
		SetListToNone(target);

		return target;
	}

	/**
	 * 将给定的对象集合转换为指定的对象集合，该方法不能复制对象内部的集合
	 * 
	 * @author QZF
	 * @param sourceList
	 * @param targetClazz
	 * @param ignoreProperties
	 * @return
	 */
	public static <S, T> List<T> objListToObjList(List<S> sourceList, Class<T> targetClazz, String... ignoreProperties)
	{
		if (sourceList == null)
		{
			return null;
		}

		if (targetClazz == null)
		{
			throw new IllegalArgumentException("Target must not be null");
		}

		return sourceList.stream().map(item -> objToObj(item, targetClazz, ignoreProperties)).collect(Collectors.toList());
	}

	/**
	 * 取出List的属性赋值为空
	 * 
	 * @author QZF
	 * @param target
	 */
	static <T> void SetListToNone(T target)
	{
		Field[] declaredFields = target.getClass().getDeclaredFields();
		for (Field f : declaredFields)
		{
			f.setAccessible(true);
			try
			{
				Object object = f.get(target);
				if (object instanceof java.util.Map || object instanceof List)
					f.set(target, null);
			}
			catch (IllegalArgumentException | IllegalAccessException e)
			{
				logger.error("", e);
			}
		}
	}
}
